<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>原型继承</title>
</head>
<body>
<h3>原型继承</h3>
<p>
    继承是面向对象编程的另一个特征，通过继承进一步提升代码封装的程度， <br>
    JavaScript 中大多是借助 原型对象 实现, 继承的特性 <br>
    事实上,还有其他继承方式, 这里只教 原型对象的继承方式
</p>
<a href="https://www.bilibili.com/video/BV1Y84y1L7Nn/?p=183&spm_id_from=pageDriver&vd_source=cb928a955f1123af004a2e3158113ea7">
    视频教程, 代码看不懂 看视频 (JS进阶 182-原型继承)
</a>
<hr>
<p>
    个人理解: 说继承 你把它理解成赋值, 就理解了 <br>
    对象 赋值给, prototype属性里
</p>

<script>
    // 男人 构造函数
    function 男人() {
        // 空内容
    }

    // 女人 构造函数
    function 女人() {
        // 空内容
    }

    // 把公共的 属性和方法, 放到原型对象里
    // const 人类 = {
    //     眼睛: 2,
    //     脑袋: 1
    // }
    // 构造函数  new 出来的对象 结构一样，但是对象不一样
    function 人类() {
      this.眼睛 = 2
      this.脑袋 = 1
    }


    // 核心思想
    // 父构造函数（父类）   子构造函数（子类）
    // 子类的原型 =  new 父类


    // 构造函数要继承, 原型对象
    男人.prototype = new 人类() // 小问题, 直接赋值会覆盖原先的内容
    男人.prototype.constructor = 男人 // 重新在指向,原先构造函数
    console.log(男人.prototype) // 即继承了属性, 又还保留 构造函数

    // 构造函数要继承, 原型对象
    女人.prototype =  new 人类()
    // 单独在添加一个方法 (这个方法,添加代码写在 继承的下面,因为上面的代码存在覆盖问题)
    女人.prototype.生孩子 = function () {
        console.log('生孩子')
    }
    女人.prototype.constructor = 女人

    // 实例化 对象
    const 王子 = new 男人()
    const 公主 = new 女人()

    console.log(王子) // 展开可以看到, 继承来的属性
    console.log(王子.眼睛) // 继承了原型对象里属性

    console.log(公主)
    公主.生孩子()
</script>
</body>
</html>